<template>
  <el-container>
    <el-col class="aside">
      <el-header style="height:30px;margin-top: 20px;">
        <span style="padding-right: 20px;">组织架构列表</span>
      </el-header>
      <el-aside style="padding-left:20px;padding-top: 10px;height: 100%">
        <div class="slot-tree">
          <el-tree
            ref="setTree"
            class="expand-tree"
            node-key="id"
            highlight-current
            :data="setTree"
            :props="defaultProps"
            :default-expanded-keys="defaultExpanded"
            :expand-on-click-node="false"
            @node-contextmenu="openMenu"
            @node-click="visible = false"
          />
        </div>
      </el-aside>

      <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
        <li @click="NodeAdd()">添加子节点</li>
        <li @click="NodeEdit">编辑改节点</li>
        <li v-if="!isHasChildren" @click="NodeDel()">删除该节点</li>
      </ul>

    </el-col>

    <!--左边节点的增删改查修改 -->
    <el-dialog
      :title="dialog.title"
      :visible.sync="dialog.show"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :modal-append-to-body="false"
    >
      <el-form
        ref="menuData"
        :model="menuData"
        :rules="form_rules"
        label-width="120px"
        style="margin:10px;width:auto;"
      >
        <el-form-item prop="name" label="名称：">
          <el-input v-model="menuData.name" type="name" />
        </el-form-item>

        <el-form-item prop="href" label="地址：">
          <el-input v-model="menuData.href" type="href" />
        </el-form-item>

        <el-form-item prop="pname" label="父级">
          <el-input v-model="menuData.pname" type="pname" disabled />
        </el-form-item>

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="closeMenu()">取 消</el-button>
        <el-button type="primary" @click="onSubmitMenu('menuData')">确 定</el-button>
      </div>
    </el-dialog>

  </el-container>
</template>
<script>
import { getOrgTree, saveOrg, delOrgData } from '@/api/user'
export default {
  data() {
    return {
      setTree: [], // 节点树数据
      iconSize: 'mini',
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      dialog: {// 添加编辑节点弹窗参数
        show: false,
        title: '',
        option: 'add',
        isTop: false
      },
      menuData: {// 节点添加对象
        checked: false,
        display: '',
        displayno: '',
        handle: '',
        href: '',
        icon: '',
        id: '',
        menuid: '',
        name: '',
        orderNum: '',
        pid: null,
        pname: null,
        psn: null,
        sn: null,
        type: ''
      },
      form_rules: {
        name: [
          { required: true, message: '名称不能为空！', trigger: 'blur' }
        ],
        href: [
          { required: true, message: '地址不能为空！', trigger: 'blur' }
        ],
        pname: [
          { required: true, message: '不能为空！', trigger: 'blur' }
        ]
      },
      treeNode: null,
      treeData: null,
      defaultExpanded: [],
      isHasChildren: true,
      left: 0,
      top: 0,
      visible: false,
      menuList: []
    }
  },
  created() {
    this.getList()
  },
  methods: {
    // 初始化获取组织结构树型结构
    getList() {
      this.setTree = [
        {
          'id': 1,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '饿了么',
          'parentId': 0,
          'sortIndex': 2,
          'type': 'org'
        },
        {
          'id': 11,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '北京总部',
          'parentId': 1,
          'sortIndex': 2,
          'type': 'org'
        },
        {
          'id': 111,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '开发组',
          'parentId': 11,
          'sortIndex': 4,
          'type': 'org'
        },
        {
          'id': 112,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '测试组',
          'parentId': 11,
          'sortIndex': 5,
          'type': 'org'

        },
        {
          'id': 1111,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '李荣浩',
          'parentId': 112,
          'sortIndex': 5,
          'type': 'user'
        },
        {
          'id': 12,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '成都分部',
          'parentId': 1,
          'sortIndex': 2,
          'type': 'org'
        },
        {
          'id': 121,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '销售部',
          'parentId': 12,
          'sortIndex': 2,
          'type': 'org'
        },
        {
          'id': 122,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '测试部',
          'parentId': 12,
          'sortIndex': 2,
          'type': 'org'
        },
        {
          'id': 123,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': '公关部',
          'parentId': 12,
          'sortIndex': 2,
          'type': 'org'
        },
        {
          'id': 1211,
          'createdTime': '2019-08-14T05:30:49.000+0000',
          'createdBy': 1,
          'lastModifiedTime': '2019-08-14T05:30:49.000+0000',
          'lastModifiedBy': 1,
          'name': 'Jay',
          'parentId': 123,
          'sortIndex': 2,
          'type': 'user'
        }
      ]
      this.setTree = this.translateDataToTree(this.setTree)
      this.defaultExpanded.push(this.setTree[0].id)
      return
      return new Promise((resolve, reject) => {
        getOrgTree().then(response => {
          this.setTree = this.translateDataToTree(response.data)
          this.defaultExpanded.push(this.setTree[0].id)
          resolve()
        }).catch(error => {
          reject(error)
        })
      })
    },
    // 生成树型结构
    translateDataToTree(data) {
      const parents = data.filter(value => value.parentId == 0)
      const childrens = data.filter(value => value.parentId !== 0)
      const translator = (parents, childrens) => {
        parents.forEach((parent) => {
          childrens.forEach((current, index) => {
            if (current.parentId === parent.id) {
              const temp = JSON.parse(JSON.stringify(childrens))
              temp.splice(index, 1)
              translator([current], temp)
              typeof parent.children !== 'undefined' ? parent.children.push(current) : parent.children = [current]
            }
          }
          )
        }
        )
      }
      translator(parents, childrens)
      return parents
    },
    // 编辑节点
    NodeEdit() { // 编辑节点
      this.dialog.show = true
      this.dialog.title = '编辑该节点'
      this.dialog.option = 'edit'
      this.dialog.isTop = false
      this.menuData = {
        'id': this.treeData.id,
        'createdTime': this.treeData.createdTime,
        'createdBy': this.treeData.createdBy,
        'lastModifiedTime': this.treeData.lastModifiedTime,
        'lastModifiedBy': this.treeData.lastModifiedBy,
        'name': this.treeData.name,
        'parentId': this.treeData.parentId,
        'sortIndex': this.treeData.sortIndex,
        'type': this.treeData.type,
        'pname': this.treeData.pname
      }
    },
    // 删除节点
    NodeDel() { // 删除节点
      if (this.treeData.children && this.treeData.children.length !== 0) {
        this.$message.error('此节点有子级，不可删除！')
        return false
      } else {
        // 新增节点可直接删除，已存在的节点要二次确认
        // 删除操作
        const DelFun = () => {
          return new Promise((resolve, reject) => {
            delOrgData(this.treeData.id).then(response => {
              if (response.message == 'success') {
                this.$message({
                  type: 'success',
                  message: '删除成功，请重新登录以刷新左侧栏目。',
                  duration: 6000
                })
                this.$refs.setTree.remove(this.treeNode)
                this.setDataToTreeDel(this.setTree, this.treeData)
                resolve()
              } else {
                this.$message({
                  type: 'error',
                  message: '删除失败!'
                })
                resolve()
              }
            }).catch(error => {
              reject(error)
            })
          })
        }
        // 二次确认
        const ConfirmFun = () => {
          this.$confirm('是否删除此节点？', '提示', {
            confirmButtonText: '确认',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            DelFun()
          }).catch(() => {
            /* this.$message({
               type: 'info',
               message: '取消删除!'
               });*/
          })
        }
        ConfirmFun()
      }
    },
    // 添加节点
    NodeAdd() { // 新增节点,
      this.dialog.show = true
      this.dialog.title = '添加子节点'
      this.dialog.option = 'add'
      this.dialog.isTop = false
      this.menuData = {
        pname: this.treeData.name,
        parentId: this.treeData.parentId,
        name: '',
        href: ''
      }
    },
    // 保存节点修改
    onSubmitMenu(form) {
      this.$refs[form].validate(valid => {
        if (valid) {
          let url = '/menu/save'
          if (this.dialog.option === 'edit') {
            url = '/menu/update'
          }
          /* if(this.menuData.pid == null && this.menuData.pname =='暂无'){
              this.menuData.pname = null
            }*/
          return new Promise((resolve, reject) => {
            saveMenu(url, this.menuData).then(response => {
              let messageHeard = '添加'
              if (this.dialog.option === 'edit') {
                messageHeard = '编辑'
              }
              if (response.message === 'success') {
                this.$message({
                  message: messageHeard + '成功，请重新登录以刷新左侧栏目。',
                  type: 'success',
                  duration: 6000
                })
                // 提交成功之后
                if (this.dialog.option === 'add') {
                  if (!this.treeData.children) {
                    this.$set(this.treeData, 'children', [])
                  }
                  this.$refs.setTree.append(response.data, this.treeNode)
                  this.setDataToTree(this.setTree, this.treeData.id, response.data)
                  if (!this.treeNode.expanded) {
                    this.treeNode.expanded = true
                  }
                } else {
                  /* this.$refs.setTree.insertAfter(response.data,this.treeNode)
                     this.$refs.setTree.remove(this.treeNode)//更新node-key的子节点*/
                  this.setDataToTreeUpdata(this.setTree, this.treeData.id, response.data)
                }
                this.dialog.show = false
                resolve()
              } else {
                this.$message({
                  message: messageHeard + '失败！',
                  type: 'error'
                })
                this.dialog.show = false
                resolve(response)
              }
            }).catch(error => {
              reject(error)
            })
          })
        }
      })
    },
    // 删除节点后数据更新
    setDataToTreeDel(treeData, curr) {
      if (treeData && treeData.length > 0) {
        for (let i = 0; i < treeData.length; i++) {
          const td = treeData[i]
          if (td.id === curr.id) {
            treeData.splice(i, 1)
            return
          } else {
            this.setDataToTreeDel(td.children, curr)
          }
        }
      }
    },
    // 修改后更新树节点信息
    setDataToTreeUpdata(treeData, pId, respData) {
      if (treeData && treeData.length > 0) {
        for (let i = 0; i < treeData.length; i++) {
          const td = treeData[i]
          if (td.id === pId) {
            treeData[i].name = respData.name
            treeData[i].href = respData.href
            return
          } else {
            this.setDataToTreeUpdata(td.children, pId, respData)
          }
        }
      }
    },
    // 添加数据后更新树信息
    setDataToTree(treeData, pId, respData) {
      if (treeData && treeData.length > 0) {
        for (let i = 0; i < treeData.length; i++) {
          const td = treeData[i]
          if (td.id === pId) {
            treeData[i].children = treeData[i].children.concat(respData)
            return
          } else {
            this.setDataToTree(td.children, pId, respData)
          }
        }
      }
    },
    // 关闭弹窗
    closeMenu() {
      this.dialog.show = false
    },
    // 右键显示栏目
    openMenu(e, object, value, element) {
      if (object.children && object.children.length > 0) {
        this.isHasChildren = true
      } else {
        this.isHasChildren = false
      }
      this.treeNode = value
      this.treeData = object
      this.treeData.pname = object.parentId === 0 ? '暂无' : value.parent.data.name
      const menuMinWidth = 105
      const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
      const offsetWidth = this.$el.offsetWidth // container width
      const maxLeft = offsetWidth - menuMinWidth // left boundary
      const left = e.clientX - offsetLeft + 20 // 15: margin right

      document.addEventListener('click', (e) => {
        this.visible = false
      })

      if (left > maxLeft) {
        this.left = maxLeft
      } else {
        this.left = left
      }
      this.top = e.clientY - 80

      this.visible = true
    }
  }
}

</script>
<style scoped >
  .slot-tree{
    width: 100%;
    height: 80%;
    margin: 0 auto;
  }
  /*顶部按钮*/
  .slot-tree .slot-t-top{
    margin-bottom: 15px;
  }
  .slot-tree .slot-t-node span{
    display: inline-block;
  }
  /*节点*/
  .slot-tree .slot-t-node--label{
    font-weight: 600;
  }
  /*输入框*/
  .slot-tree .slot-t-input .el-input__inner{
    height: 26px;
    line-height: 26px;
  }
  /*按钮列表*/
  .slot-tree .slot-t-node .slot-t-icons{
    display: none;
    margin-left: 10px;
  }
  .slot-tree .slot-t-icons .el-button+.el-button{
    margin-left: 6px;
  }
  .slot-tree .el-tree-node__content:hover .slot-t-icons{
    display: inline-block;
  }
  .contextmenu {
    margin: 0;
    background: #fff;
    z-index: 100;
    position: absolute;
    list-style-type: none;
    padding: 5px 0;
    border-radius: 4px;
    font-size: 14px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);

  }
  .contextmenu li {
    margin: 0;
    padding: 7px 16px;
    cursor: pointer;
  }
  .contextmenu li:hover {
    background: #eee;
  }

</style>
